package com.ruoyi.web.controller.net;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.net.domain.*;
import com.ruoyi.net.netconf.Device;
import com.ruoyi.net.netconf.util.DeviceManager;
import com.ruoyi.net.service.*;
import com.ruoyi.system.service.ISysConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.util.StringBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 业务-L2 VPN配置Controller
 * 
 * @author net
 * @date 2024-12-14
 */
@Api(tags = "业务-L2 VPN配置")
@RestController
@RequestMapping("/busi/l2/vpn")
public class BusiL2VpnController extends BaseController {
    @Autowired
    private IBusiL2VpnService busiL2VpnService;

    @Autowired
    private DeviceManager deviceManager;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private INetElementService netElementService;

    @Autowired
    private IElementMplsLsridService mplsLsridService;

    @Autowired
    private IBusiL2VpnPwService l2VpnPwService;

    @Autowired
    private IBusiL2VpnTunnelStrategyService tunnelStrategyService;

    @Autowired
    private IBusiElementStatusService busiElementStatusService;

    @Autowired
    private IBusiL2VpnAlarmoamService alarmoamService;

    @Autowired
    private IBusiL2VpnNodeService nodeService;

    @Autowired
    private IBusiMplstpElementService mplstpElementService;

    /**
     * 查询业务-L2 VPN配置列表(单站需要设备elementId的值）
     */
    @ApiOperation(value = "查询业务-L2 VPN配置列表(单站需要设备elementId的值）", httpMethod = "GET")
    @PreAuthorize("@ss.hasPermi('net:vpn:list')")
    @GetMapping("/list")
    public TableDataInfo list(BusiL2VpnVo busiL2VpnVo) {
        startPage();
//        List<BusiL2VpnVo> list = busiL2VpnService.selectBusiL2VpnList(busiL2VpnVo);
        List<BusiL2VpnVo> list = busiL2VpnService.selectBusiL2VpnListVo(busiL2VpnVo);
        return getDataTable(list);
    }


    /**
     * 查询网元-业务-eline列表
     */
    @ApiOperation(value = "查询网元-业务-eline列表(单站需要设备elementId的值）", httpMethod = "GET")
    @GetMapping("/ele/list")
//    public TableDataInfo eleList(BusiL2VpnEleListVo busiL2Vpn) {
    public TableDataInfo eleList(BusiL2VpnVo busiL2VpnVo) {
        startPage();
//        List<BusiL2VpnEleListVo> list = busiL2VpnService.selectBusiL2VpnEleList(busiL2Vpn);
        List<BusiL2VpnVo> list = busiL2VpnService.selectBusiL2VpnListVo(busiL2VpnVo);
        return getDataTable(list);
    }

    /**
     * 导出业务-L2 VPN配置列表
     */
    @ApiOperation(value = "导出业务-L2 VPN配置列表", httpMethod = "POST")
    @PreAuthorize("@ss.hasPermi('net:vpn:export')")
    @Log(title = "业务-L2 VPN配置", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BusiL2Vpn busiL2Vpn) {
        List<BusiL2Vpn> list = busiL2VpnService.selectBusiL2VpnList(busiL2Vpn);
        ExcelUtil<BusiL2Vpn> util = new ExcelUtil<BusiL2Vpn>(BusiL2Vpn.class);
        util.exportExcel(response, list, "业务-L2 VPN配置数据");
    }

    /**
     * 获取业务-L2 VPN配置详细信息
     */
    @ApiOperation(value = "获取业务-L2 VPN配置详细信息", httpMethod = "GET")
    @PreAuthorize("@ss.hasPermi('net:vpn:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return success(busiL2VpnService.selectBusiL2VpnById(id));
    }

    /**
     * 新增业务-L2 VPN配置
     */
    @ApiOperation(value = "新增业务-L2 VPN配置", httpMethod = "POST")
    @PreAuthorize("@ss.hasPermi('net:vpn:add')")
    @Log(title = "业务-L2 VPN配置", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BusiL2Vpn busiL2Vpn) {
        return toAjax(busiL2VpnService.insertBusiL2Vpn(busiL2Vpn));
    }

    /**
     * 修改业务-L2 VPN配置
     */
    @ApiOperation(value = "修改业务-L2 VPN配置", httpMethod = "PUT")
    @PreAuthorize("@ss.hasPermi('net:vpn:edit')")
    @Log(title = "业务-L2 VPN配置", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BusiL2Vpn busiL2Vpn) {
        return toAjax(busiL2VpnService.updateBusiL2Vpn(busiL2Vpn));
    }

    /**
     * 删除业务-L2 VPN配置
     */
    @ApiOperation(value = "删除业务-L2 VPN配置", httpMethod = "DELETE")
    @PreAuthorize("@ss.hasPermi('net:vpn:remove')")
    @Log(title = "业务-L2 VPN配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
        return toAjax(busiL2VpnService.deleteBusiL2VpnByIds(ids));
    }

    @ApiOperation(value = "点击'完成'按钮更新业务-L2 VPN配置状态", httpMethod = "PUT")
    @PreAuthorize("@ss.hasPermi('net:vpn:edit')")
    @Log(title = "业务-L2 VPN配置", businessType = BusinessType.UPDATE)
    @PutMapping("/complete")
    public AjaxResult complete(@RequestBody BusiL2Vpn busiL2Vpn) {
        return toAjax(busiL2VpnService.updateBusiL2Vpn(busiL2Vpn));
    }

    /**
     * 单站激活设备
     * */
    @ApiOperation(value = "单站激活设备", httpMethod = "GET")
    @Log(title = "单站激活设备", businessType = BusinessType.UPDATE)
    @GetMapping(value = "/activate/{l2VpnId}/{elementId}")
    public AjaxResult activateDevice(@PathVariable("l2VpnId") String l2VpnId, @PathVariable("elementId") String elementId) {
        try {
            AjaxResult.success(activateElement(l2VpnId, elementId));
        } catch (Exception e) {
            logger.error("激活失败", e);
            return AjaxResult.error("激活失败");
        }
        return AjaxResult.success("激活成功");
    }

    /**
     * 单站去激活设备
     * */
    @ApiOperation(value = "单站去激活设备", httpMethod = "GET")
    @Log(title = "单站去激活设备", businessType = BusinessType.UPDATE)
    @GetMapping(value = "/unactivate/{l2VpnId}/{elementId}")
    public AjaxResult unactivateDevice(@PathVariable("l2VpnId") String l2VpnId, @PathVariable("elementId") String elementId) {
        try {
            unactivateElement(l2VpnId, elementId);
        } catch (Exception e) {
            logger.error("去激活失败", e);
            return AjaxResult.success("去激活失败");
        }
        return AjaxResult.success("去激活成功");
    }

    /**
     * 激活设备 批量
     *
     * @param id
     */
    @ApiOperation(value = "激活设备", httpMethod = "GET")
    @GetMapping(value = "/activate/{id}")
    @Log(title = "激活设备", businessType = BusinessType.UPDATE)
    public AjaxResult activateDevice(@PathVariable("id") String id) {
        String status = "0";
        BusiL2Vpn entity = busiL2VpnService.selectBusiL2VpnById(id);
        try {
            BusiL2VpnEleListVo busiL2Vpn = new BusiL2VpnEleListVo();
            busiL2Vpn.setId(id);
            List<BusiL2VpnEleListVo> list = busiL2VpnService.selectBusiL2VpnEleList(busiL2Vpn);
            if("一源一宿".equals(entity.getNetworkMode())) {
                status = sendXml(list);
            }
            else {
                status = protectActivateDevice(entity.getId(), "");
            }
            entity.setStatus(status);
            return toAjax(busiL2VpnService.updateBusiL2Vpn(entity));
        } catch (Exception e) {
            logger.error("激活业务失败：", e);
            return AjaxResult.error("激活设备失败");
        }
    }

    /**
     * 去激活设备 批量
     *
     * @param id
     */
    @ApiOperation(value = "去激活设备", httpMethod = "GET")
    @Log(title = "去激活设备", businessType = BusinessType.UPDATE)
    @GetMapping(value = "/unactivate/{id}")
    public AjaxResult unactivateDevice(@PathVariable("id") String id) {
        BusiL2Vpn entity = busiL2VpnService.selectBusiL2VpnById(id);
        BusiL2VpnEleListVo busiL2Vpn = new BusiL2VpnEleListVo();
        busiL2Vpn.setId(id);
        List<BusiL2VpnEleListVo> list = busiL2VpnService.selectBusiL2VpnEleList(busiL2Vpn);
        String status = "0";
        status = batchUnactivateL2Vpn(list);
        entity.setStatus(status);
        return toAjax(busiL2VpnService.updateBusiL2Vpn(entity));
    }

    /**
     * 发送xml到设备
     *
     * @param list
     */
    private String sendXml(List<BusiL2VpnEleListVo> list) throws Exception {
        String status = "0";
        int activateCount = 0;
        // 源网元
        String startLsrIp = "";
        // 宿网元
        String endLsrIp = "";
        // 备用宿网元
        String bakLsrIp = "";
        for (BusiL2VpnEleListVo entity : list) {
            // 获取 lsp id
            ElementMplsLsrid elementMplsLsrid = new ElementMplsLsrid();
            elementMplsLsrid.setElementId(entity.getElementId());
            List<ElementMplsLsrid> lsrids = mplsLsridService.selectElementMplsLsridList(elementMplsLsrid);
            if (lsrids == null || lsrids.isEmpty()) {
                throw new RuntimeException("获取LSR ID失败");// 默认去loopback0对应的
            }
            lsrids = lsrids.stream().filter(lsrId -> lsrId.getLsrId().startsWith("loopback0")).collect(Collectors.toList());
            if (lsrids == null || lsrids.isEmpty()) {
                throw new RuntimeException("获取LSR ID失败, 缺少loopback0");// 默认去loopback0对应的
            }
            // <destination>100.1.1.2</destination>//关键字，隧道目的地址，目的网元的MPLS LSR ID
            String destination = lsrids.get(0).getLsrId().replaceAll("\\)", "").split("\\(")[1];
            if (entity.getNodeRole().equals("源网元")) {
                startLsrIp = destination;
            } else if (entity.getNodeRole().equals("宿网元")) {
                endLsrIp = destination;
            } else {
                bakLsrIp = destination;
            }
        }

        for (BusiL2VpnEleListVo entity : list) {
            boolean isSend = false;
            String destination = "";
            String peerIp = "";
            String tunnelId = "";
            // 获取网元信息， ip
            NetElement netElement = netElementService.getCacheObject(entity.getElementId());
            // 获取pw
            BusiL2VpnPw busiL2VpnPw = new BusiL2VpnPw();
            busiL2VpnPw.setL2VpnId(entity.getId());
            List<BusiL2VpnPwListVo> pws = l2VpnPwService.selectBusiL2VpnPwList(busiL2VpnPw);
            BusiL2VpnPwListVo busiL2VpnPwVo = pws.get(0);

            // 获取 隧道策略
            BusiL2VpnTunnelStrategy tunnelStrategy = new BusiL2VpnTunnelStrategy();
            tunnelStrategy.setL2VpnId(entity.getId());
            tunnelStrategy.setTunnelType(busiL2VpnPwVo.getTunnelType());
            tunnelStrategy.setTunelBusiId(busiL2VpnPwVo.getServiceLayerId());
            List<BusiL2VpnTunnelStrategy> tunnelStrategies = tunnelStrategyService.selectBusiL2VpnTunnelStrategyList(tunnelStrategy);
            tunnelStrategy = tunnelStrategies.get(0);

            logger.info(String.format("调试获取tunnelId参数信息：ServiceLayerId-{0} startE-{1} endE-{2} role-{3}" + busiL2VpnPwVo.getServiceLayerId() + "," + busiL2VpnPwVo.getStartElementId() + "," + busiL2VpnPwVo.getEndElementId() + "," + busiL2VpnPwVo.getRole()));
            if (entity.getNodeRole().equals("源网元")) {
                destination = endLsrIp;
                peerIp = endLsrIp;
                // 通过 mpls的服务和设备去查tunnelId
                tunnelId = getTunnelIdByServiceLayerIdAndElementId(busiL2VpnPwVo.getServiceLayerId(), busiL2VpnPwVo.getStartElementId(), busiL2VpnPwVo.getRole());
            } else if (entity.getNodeRole().equals("宿网元")) {
                destination = startLsrIp;
                peerIp = startLsrIp;
                tunnelId = getTunnelIdByServiceLayerIdAndElementId(busiL2VpnPwVo.getServiceLayerId(), busiL2VpnPwVo.getEndElementId(), busiL2VpnPwVo.getRole());
            } else {
                destination = bakLsrIp;
                peerIp = bakLsrIp;
                tunnelId = getTunnelIdByServiceLayerIdAndElementId(busiL2VpnPwVo.getServiceLayerId(), busiL2VpnPwVo.getEndElementId(), busiL2VpnPwVo.getRole());
            }

            // 配置隧道策略 xml
            StringBuilder policyXml = new StringBuilder();
            policyXml.append("<tnl-plcy xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-tunnelpolicy\">" +
                    "        <tunnel-policies>" +
                    "          <tunnel-policy-list>" +
                    "            <tunnel-policy-name>" + tunnelStrategy.getBusiName() + "</tunnel-policy-name>" + // pw-tnl-plcy-1534918703关键字，隧道策略名
                    "            <tunnel-policy-mode>" + tunnelStrategy.getTunnelStrategyMode() + "</tunnel-policy-mode>" + // TUNNEL-BINGDING 隧道策略配置模式
                    "            <binding-policy>" +
                    "              <destination>" + destination + "</destination>" + //关键字，隧道目的地址，目的网元的MPLS LSR ID
//                    "              <tunnel-id>" + busiL2VpnPwVo.getVcId() + "</tunnel-id>" + // 1被绑定的隧道接口或隧道保护组接口id
                    "              <tunnel-id>" + tunnelId + "</tunnel-id>" + // 1被绑定的隧道接口或隧道保护组接口id
                    "              <tunnel-down-switch>" + busiL2VpnPwVo.getTunnelSwitch() + "</tunnel-down-switch>" + //disable 使能隧道切换功能
                    "              <bind-tnnl-type>bind-tunnel</bind-tnnl-type>" + //被绑定的类型，取bind-tunnel，表示绑定的是隧道；取bind-bundle，表示绑定的是保护组
                    "            </binding-policy>" +
                    "          </tunnel-policy-list>" +
                    "        </tunnel-policies>" +
                    "      </tnl-plcy>");

            // PW-CLASS配置
            StringBuilder pwClassXml = new StringBuilder();
            pwClassXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                    "        <pw-class>" +
                    "          <pw-class-list>" +
                    "            <pw-class-name>" + busiL2VpnPwVo.getPwClassName() + "</pw-class-name>" + //PW模板名，关键字 pwclassname-1534918717
                    "            <control-word>" + busiL2VpnPwVo.getControlEnable() + "</control-word>" +//控制字 enable
                    "            <tunnel-policy>" + tunnelStrategy.getBusiName() + "</tunnel-policy>" +//隧道策略，引用2的名字 pw-tnl-plcy-1534918703
                    "          </pw-class-list>" +
                    "        </pw-class>" +
                    "      </l2vpn>");

            // VPWS实例配置
            StringBuilder vpwsXml = new StringBuilder();
            vpwsXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                    "        <vpws>" +
                    "          <vpws-list>" +
                    "            <service-name>" + entity.getNodeBusiName() + "</service-name>" +//关键字，VPWS名称 vpws_1
                    "            <accessif-list>" +//UNI口
                    "              <ac-name>" + entity.getPortName() + "</ac-name>" + //eth-1gi0/1/0/2.2 元网元店铺
                    "            </accessif-list>" +
                    "            <pw-list>" +//PW列表
                    "              <peer-ip>" + peerIp + "</peer-ip>" +//关键字，对端IP地址 100.1.1.2
                    "              <pw-id>" + busiL2VpnPwVo.getVcId() + "</pw-id>" +//关键字，VC ID 1
                    "              <pw-type>raw</pw-type>" +//封装类型
                    "              <static-transmit-label>" + busiL2VpnPwVo.getOutLabel() + "</static-transmit-label>" +//出标签，16-768432 21
                    "              <static-receive-label>" + busiL2VpnPwVo.getInLabel() + "</static-receive-label>" +//入标签，16-768432 21
                    "              <pw-role>primary</pw-role>" +//保护角色
                    "              <pw-class-name>" + busiL2VpnPwVo.getPwClassName() + "</pw-class-name>" +//引用PW模板，3中配置 pwclassname-1534918717
                    "            </pw-list>" +
//                    "            <vpws-qos-cfg xmlns=\"http://fiberhome.com/fhnw/yang/qos/fos-qos\"/>" +
                    "          </vpws-list>" +
                    "        </vpws>" +
                    "      </l2vpn>");
            logger.info("L2VPN业务配置 配置隧道策略 xml:{}", policyXml);
            logger.info("L2VPN业务配置 PW-CLASS配置 xml:{}", pwClassXml);
            logger.info("L2VPN业务配置 VPWS实例配置 xml:{}", vpwsXml);
            Device device = deviceManager.getDevice(netElement.getIp());
            if (device.isConnected()) {
                isSend = deviceManager.editConfig(policyXml.toString(), "merge");
                isSend = deviceManager.editConfig(pwClassXml.toString(), "merge");
                isSend = deviceManager.editConfig(vpwsXml.toString(), "merge");
            }
            if (isSend) {
                activateCount += updateElementStatus(entity.getId(), entity.getElementId(), "1");
            }
        }
        if (activateCount == list.size()) {
            status = "1";
        } else if (activateCount == 0) {
            status = "0";
        } else if (activateCount < list.size()) {
            status = "2";
        }
        return status;
    }

    /**
     * 单站激活
     * @param l2VpnId
     * @param elementId
     */
    public boolean activateElement(String l2VpnId, String elementId) throws Exception {
        boolean isSend = false;
        BusiL2Vpn busiL2Vpn = busiL2VpnService.selectBusiL2VpnById(l2VpnId);
        BusiL2VpnEleListVo tempBusiL2VpnVo = new BusiL2VpnEleListVo();
        tempBusiL2VpnVo.setId(l2VpnId);
        List<BusiL2VpnEleListVo> list = busiL2VpnService.selectBusiL2VpnEleList(tempBusiL2VpnVo);

        // 当前网元
        BusiL2VpnEleListVo vpnEleListVo = null;
        for (BusiL2VpnEleListVo entity : list) {
            if (elementId.equals(entity.getElementId())) {
                vpnEleListVo = entity;
            }
        }
        if (vpnEleListVo != null) {
            // xml报文列表
            List<String> alarmOamXmlList = new ArrayList<>();
            List<String> tunnelPolcyXmlList = new ArrayList<>();
            List<String> pwClassXmlList = new ArrayList<>();
            List<BusiL2VpnAlarmoam> alarmoamList = new ArrayList<>();
            if ("一源两宿".equals(busiL2Vpn.getNetworkMode())) {
                // OAM
                BusiL2VpnAlarmoam alarmoam = new BusiL2VpnAlarmoam();
                alarmoam.setL2VpnId(l2VpnId);
                alarmoam.setElementId(elementId);
                alarmoamList = alarmoamService.selectBusiL2VpnAlarmoamList(alarmoam);
                for (BusiL2VpnAlarmoam tempAlarmoam : alarmoamList) {
                    StringBuilder oamXml = new StringBuilder();
                    String[] meg = tempAlarmoam.getMeg().split("/");
                    String[] ttl = tempAlarmoam.getLspTtl().split("/");
                    oamXml.append("<tpoam xmlns=\"http://fiberhome.com/fhnw/yang/oam/fos-tpoam\">" +
                            "    <meg-cfg>" +
                            "      <meg-list>" +
                            "        <meg-name>" + tempAlarmoam.getMegName() + "</meg-name>" +//meg5b7d003f
                            "        <level>" + meg[4] + "</level>" +
                            "        <icc>" + meg[0] + "</icc>" +
                            "        <umc>" + meg[1] + "</umc>" +
                            "        <me-list>" +
                            "          <me-name>" + tempAlarmoam.getMeName() + "</me-name>" +
                            "          <mep-id>" + meg[2] + "</mep-id>" +
                            "          <remote-mep-id>" + meg[3] + "</remote-mep-id>" +
                            "          <mp-type>" + tempAlarmoam.getMpType() + "</mp-type>" + // mep
                            "          <ccm-send-enable>enable</ccm-send-enable>" +
                            "          <ccm-interval>" + tempAlarmoam.getCv() + "</ccm-interval>" +//3_33ms
                            "          <aps-send-enable>" + tempAlarmoam.getAps() + "</aps-send-enable>" + // disable
                            "          <fdi-send-enable>" + tempAlarmoam.getFdi() + "</fdi-send-enable>" + // disable
                            "          <csf-send-enable>" + tempAlarmoam.getCsf() + "</csf-send-enable>" + // disable
                            "          <oam-exp>" + ttl[1] + "</oam-exp>" +
                            "          <oam-ttl>" + ttl[0] + "</oam-ttl>" +
                            "          <dual-lm-enable>disable</dual-lm-enable>" +
                            "        </me-list>" +
                            "      </meg-list>" +
                            "    </meg-cfg>" +
                            "  </tpoam>");

                    alarmOamXmlList.add(oamXml.toString());
                }
            }
            // 获取pw
            List<String> partPwListXmlList = new ArrayList<>();
            BusiL2VpnPw busiL2VpnPw = new BusiL2VpnPw();
            busiL2VpnPw.setL2VpnId(l2VpnId);
            if ("源网元".equals(vpnEleListVo.getNodeRole())) {
                busiL2VpnPw.setStartElementId(vpnEleListVo.getElementId());
            } else if ("宿网元".equals(vpnEleListVo.getNodeRole())) {
                busiL2VpnPw.setEndElementId(vpnEleListVo.getElementId());
            } else if ("备用宿网元".equals(vpnEleListVo.getNodeRole())) {
                busiL2VpnPw.setEndElementId(vpnEleListVo.getElementId());
            }
            List<BusiL2VpnPwListVo> pws = new ArrayList<>();
            pws = l2VpnPwService.selectBusiL2VpnPwList(busiL2VpnPw);
            int i = 0;
            for (BusiL2VpnPwListVo pw : pws) {
                // 获取 隧道策略
                BusiL2VpnTunnelStrategy tunnelStrategy = new BusiL2VpnTunnelStrategy();
                tunnelStrategy.setL2VpnId(l2VpnId);
                tunnelStrategy.setTunnelType(pw.getTunnelType());
                tunnelStrategy.setTunelBusiId(pw.getServiceLayerId());
                List<BusiL2VpnTunnelStrategy> tunnelStrategies = tunnelStrategyService.selectBusiL2VpnTunnelStrategyList(tunnelStrategy);
                tunnelStrategy = tunnelStrategies.get(0);
                String lsrIp = "";
                String tunnelId = "";
                BusiL2VpnNodeListVo nodeListVo = null;
                logger.info(String.format("调试获取tunnelId参数信息-单站：ServiceLayerId-{0} startE-{1} endE-{2} role-{3} " + pw.getServiceLayerId() + "," +  pw.getStartElementId() + "," + pw.getEndElementId() + "," + pw.getRole()));
                if ("源网元".equals(vpnEleListVo.getNodeRole())) {
                    lsrIp = getLsrIpByElementId(pw.getEndElementId());
                    nodeListVo = getL2VpnNodeRole(l2VpnId, pw.getEndElementId());
                    // 通过 mpls的服务和设备去查tunnelId
                    tunnelId = getTunnelIdByServiceLayerIdAndElementId(pw.getServiceLayerId(), pw.getStartElementId(), pw.getRole());
                } else {
                    lsrIp = getLsrIpByElementId(pw.getStartElementId());
                    nodeListVo = getL2VpnNodeRole(l2VpnId, pw.getStartElementId());
                    tunnelId = getTunnelIdByServiceLayerIdAndElementId(pw.getServiceLayerId(), pw.getEndElementId(), pw.getRole());
                }
                // 配置隧道策略 xml
                StringBuilder tunnelPolicyXml = new StringBuilder();
                tunnelPolicyXml.append("<tnl-plcy xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-tunnelpolicy\">" +
                        "        <tunnel-policies>" +
                        "          <tunnel-policy-list>" +
                        "            <tunnel-policy-name>" + tunnelStrategy.getBusiName() + "</tunnel-policy-name>" + // pw-tnl-plcy-1534918703关键字，隧道策略名
                        "            <tunnel-policy-mode>" + tunnelStrategy.getTunnelStrategyMode() + "</tunnel-policy-mode>" + // TUNNEL-BINGDING 隧道策略配置模式
                        "            <binding-policy>" +
                        "              <destination>" + lsrIp + "</destination>" + //关键字，隧道目的地址，目的网元的MPLS LSR ID
//                        "              <tunnel-id>" + pw.getVcId() + "</tunnel-id>" + // 1被绑定的隧道接口或隧道保护组接口id
                        "              <tunnel-id>" + tunnelId + "</tunnel-id>" + // 1被绑定的隧道接口或隧道保护组接口id
                        "              <tunnel-down-switch>" + pw.getTunnelSwitch() + "</tunnel-down-switch>" + //disable 使能隧道切换功能
                        "              <bind-tnnl-type>bind-tunnel</bind-tnnl-type>" + //被绑定的类型，取bind-tunnel，表示绑定的是隧道；取bind-bundle，表示绑定的是保护组
                        "            </binding-policy>" +
                        "          </tunnel-policy-list>" +
                        "        </tunnel-policies>" +
                        "      </tnl-plcy>");
                tunnelPolcyXmlList.add(tunnelPolicyXml.toString());
                // PW-CLASS配置
                StringBuilder pwClassXml = new StringBuilder();
                pwClassXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                        "        <pw-class>" +
                        "          <pw-class-list>" +
                        "            <pw-class-name>" + pw.getPwClassName() + "</pw-class-name>" + //PW模板名，关键字 pwclassname-1534918717
                        "            <control-word>" + pw.getControlEnable() + "</control-word>" +//控制字 enable
                        "            <tunnel-policy>" + tunnelStrategy.getBusiName() + "</tunnel-policy>" +//隧道策略，引用2的名字 pw-tnl-plcy-1534918703
                        "          </pw-class-list>" +
                        "        </pw-class>" +
                        "      </l2vpn>");
                pwClassXmlList.add(pwClassXml.toString());
                StringBuilder partPwListXml = new StringBuilder();
                partPwListXml.append("<pw-list>" +
                        "          <peer-ip>" + lsrIp + "</peer-ip>" +
                        "          <pw-id>" + pw.getVcId() + "</pw-id>" +
                        "          <pw-type>raw</pw-type>" +
                        "          <static-transmit-label>" + pw.getOutLabel() + "</static-transmit-label>" +
                        "          <static-receive-label>" + pw.getInLabel() + "</static-receive-label>" +
                        "          <pw-role>" + ("备用宿网元".equals(nodeListVo.getNodeRole()) ? "secondary" : "primary") + "</pw-role>" +
                        "          <pw-class-name>" + pw.getPwClassName() + "</pw-class-name>");// + // pwclassname-1534918720
                if ("一源两宿".equals(busiL2Vpn.getNetworkMode())) {
                    partPwListXml.append("          <vcoam xmlns=\"http://fiberhome.com/fhnw/yang/oam/fos-tpoam\">" + //PW  OAM
                            "            <me-name>" + alarmoamList.get(i).getMeName() + "</me-name>" +
                            "          </vcoam>");
                }
                partPwListXml.append("        </pw-list>");
                partPwListXmlList.add(partPwListXml.toString());

                i++;
            }

            //VPWS实例配置
            StringBuilder vpwsXml = new StringBuilder();
            vpwsXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                    "    <vpws>" +
                    "      <vpws-list>" +
                    "        <service-name>" + vpnEleListVo.getNodeBusiName() + "</service-name>"); //PW 保护属性
            if ("一源两宿".equals(busiL2Vpn.getNetworkMode()) && "源网元".equals(vpnEleListVo.getNodeRole())) {
                vpwsXml.append("        <wtr>5</wtr>" +
                        "        <holdtime>0</holdtime>" +
                        "        <revertive-mode>revertive</revertive-mode>" +
                        "        <protect-type>redundancy</protect-type>");
            }
            vpwsXml.append("        <accessif-list>" +
                    "          <ac-name>" + vpnEleListVo.getPortName() + "</ac-name>" +
                    "        </accessif-list>");
            for (String strPartPwListXml : partPwListXmlList) {
                vpwsXml.append(strPartPwListXml);
            }
            vpwsXml.append(//"        <vpws-qos-cfg xmlns=\"http://fiberhome.com/fhnw/yang/qos/fos-qos\"/>" +
                    "      </vpws-list>" +
                    "    </vpws>" +
                    "  </l2vpn>");
            for (String oamXml : alarmOamXmlList) {
                logger.info("L2VPN业务配置 OAM xml:{}", oamXml);
            }
            for (String tunnelPolicyXml : tunnelPolcyXmlList) {
                logger.info("L2VPN业务配置 配置隧道策略 xml:{}", tunnelPolicyXml);
            }
            for (String pwClassXml : pwClassXmlList) {
                logger.info("L2VPN业务配置 PW-CLASS配置 xml:{}", pwClassXml);
            }
            logger.info("L2VPN业务配置 VPWS实例配置 xml:{}", vpwsXml);

            // 获取网元信息， ip
            NetElement netElement = netElementService.getCacheObject(vpnEleListVo.getElementId());

            Device device = deviceManager.getDevice(netElement.getIp());
            if (device.isConnected()) {
                for (String oamXml : alarmOamXmlList) {
                    // 配置OAM
                    isSend = deviceManager.editConfig(oamXml, "merge");
                }

                for (String tunnelPolicyXml : tunnelPolcyXmlList) {
                    // 配置隧道策略
                    isSend = deviceManager.editConfig(tunnelPolicyXml, "merge");
                }

                for (String pwClassXml : pwClassXmlList) {
                    // 配置PW-CLASS
                    isSend = deviceManager.editConfig(pwClassXml, "merge");
                }

                isSend = deviceManager.editConfig(vpwsXml.toString(), "merge");
            }
        }
        if (isSend) {
            updateElementStatus(l2VpnId, elementId, "1"); // 激活
        }
        return isSend;
    }

    /**
     * 获取隧道ID
     * @param serviceLayerId
     * @param elementId
     * @param role
     * @return
     */
    private String getTunnelIdByServiceLayerIdAndElementId(String serviceLayerId, String elementId, String role) {
        String tunnelId = "";
        String routeType = "工作".equals(role) ? "1" : "2";
        BusiMplstpElement busiMplstpElement = new BusiMplstpElement();
        busiMplstpElement.setMplstpId(serviceLayerId);
        busiMplstpElement.setElementId(elementId);
        busiMplstpElement.setRouteType(routeType);
        List<BusiMplstpElement> list = mplstpElementService.selectBusiMplstpElementList(busiMplstpElement);
        if (!list.isEmpty()) {
            tunnelId = list.get(0).getPositiveTunnelId();
        }
        return tunnelId;
    }

    /**
     * 单站去激活/ 多站去激活
     * @param l2VpnId
     * @param elementId
     */
    private boolean unactivateElement(String l2VpnId, String elementId) throws Exception {
        boolean isSend = false;
        BusiL2Vpn busiL2Vpn = busiL2VpnService.selectBusiL2VpnById(l2VpnId);

        BusiL2VpnEleListVo vpnEleListVo = new BusiL2VpnEleListVo();
        vpnEleListVo.setId(l2VpnId);
        if (StringUtils.isNotEmpty(elementId)) {
            vpnEleListVo.setElementId(elementId);
        }
        List<BusiL2VpnEleListVo> vpnEleListVos = busiL2VpnService.selectBusiL2VpnEleList(vpnEleListVo);
        for (BusiL2VpnEleListVo tempVpnEleListVo : vpnEleListVos) {
            if (elementId.equals(tempVpnEleListVo.getElementId())) {
                vpnEleListVo = tempVpnEleListVo;
            }
        }
        // 隧道策略
        List<String> tunnelPolicyXmlList = new ArrayList<>();
        // PW-CLASS配置
        List<String> pwClassXmlList = new ArrayList<>();
        // OAM配置
        List<String> oamXmlList = new ArrayList<>();
        // 获取pw
        BusiL2VpnPw busiL2VpnPw = new BusiL2VpnPw();
        busiL2VpnPw.setL2VpnId(l2VpnId);
        if ("源网元".equals(vpnEleListVo.getNodeRole())) {
            busiL2VpnPw.setStartElementId(elementId);
        }
        else {
            busiL2VpnPw.setEndElementId(elementId);
        }
        List<BusiL2VpnPwListVo> pws = l2VpnPwService.selectBusiL2VpnPwList(busiL2VpnPw);

        for (BusiL2VpnPwListVo busiL2VpnPwVo : pws) {
            // 获取 隧道策略
            BusiL2VpnTunnelStrategy tunnelStrategy = new BusiL2VpnTunnelStrategy();
            tunnelStrategy.setL2VpnId(l2VpnId);
            tunnelStrategy.setTunnelType(busiL2VpnPwVo.getTunnelType());
            tunnelStrategy.setTunelBusiId(busiL2VpnPwVo.getServiceLayerId());
            List<BusiL2VpnTunnelStrategy> tunnelStrategies = tunnelStrategyService.selectBusiL2VpnTunnelStrategyList(tunnelStrategy);
            tunnelStrategy = tunnelStrategies.get(0);
            // 配置隧道策略 xml
            StringBuilder policyXml = new StringBuilder();
            policyXml.append("<tnl-plcy xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-tunnelpolicy\">" +
                    "        <tunnel-policies>" +
                    "          <tunnel-policy-list nc:operation=\"remove\">" +
                    "            <tunnel-policy-name>" + tunnelStrategy.getBusiName() + "</tunnel-policy-name>" + // pw-tnl-plcy-1534918703关键字，隧道策略名
                    "            <tunnel-policy-mode>" + tunnelStrategy.getTunnelStrategyMode() + "</tunnel-policy-mode>" + // TUNNEL-BINGDING 隧道策略配置模式
                    "          </tunnel-policy-list>" +
                    "        </tunnel-policies>" +
                    "      </tnl-plcy>");
            tunnelPolicyXmlList.add(policyXml.toString());
            // PW-CLASS配置
            StringBuilder pwClassXml = new StringBuilder();
            pwClassXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                    "        <pw-class>" +
                    "          <pw-class-list nc:operation=\"remove\">" +
                    "            <pw-class-name>" + busiL2VpnPwVo.getPwClassName() + "</pw-class-name>" + //PW模板名，关键字 pwclassname-1534918717
//                "            <control-word>" + busiL2VpnPwVo.getControlEnable() + "</control-word>" +//控制字 enable
//                "            <tunnel-policy>" + tunnelStrategy.getBusiName() + "</tunnel-policy>" +//隧道策略，引用2的名字 pw-tnl-plcy-1534918703
                    "          </pw-class-list>" +
                    "        </pw-class>" +
                    "      </l2vpn>");
            pwClassXmlList.add(pwClassXml.toString());
        }
        // OAM
        if ("一源两宿".equals(busiL2Vpn.getNetworkMode())) {
            BusiL2VpnAlarmoam busiL2VpnAlarmoam = new BusiL2VpnAlarmoam();
            busiL2VpnAlarmoam.setL2VpnId(l2VpnId);
            busiL2VpnAlarmoam.setElementId(elementId);

            List<BusiL2VpnAlarmoam> alarmoamList = alarmoamService.selectBusiL2VpnAlarmoamList(busiL2VpnAlarmoam);
            for (BusiL2VpnAlarmoam alarmoam : alarmoamList) {
                StringBuilder oamXml = new StringBuilder();
                oamXml.append("<tpoam xmlns=\"http://fiberhome.com/fhnw/yang/oam/fos-tpoam\">" +
                        "    <meg-cfg>" +
                        "      <meg-list nc:operation=\"remove\">" +
                        "        <meg-name>" + alarmoam.getMegName() + "</meg-name>" +
                        "      </meg-list>" +
                        "    </meg-cfg>" +
                        "  </tpoam>");
                oamXmlList.add(oamXml.toString());
            }
        }
        // VPWS实例配置
        StringBuilder vpwsXml = new StringBuilder();
        vpwsXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                "        <vpws>" +
                "          <vpws-list nc:operation=\"remove\">" +
                "            <service-name>" + vpnEleListVo.getNodeBusiName() + "</service-name>" +//关键字，VPWS名称 vpws_1
                "          </vpws-list>" +
                "        </vpws>" +
                "      </l2vpn>");
        logger.info("L2VPN业务配置 VPWS实例配置 去激活 xml:{}", vpwsXml);
        for (String policyXml : tunnelPolicyXmlList) {
            logger.info("L2VPN业务配置 配置隧道策略 去激活 xml:{}", policyXml);
        }
        for(String pwClassXml : pwClassXmlList) {
            logger.info("L2VPN业务配置 PW-CLASS配置 去激活 xml:{}", pwClassXml);
        }
        for(String oamXml : oamXmlList) {
            logger.info("L2VPN业务配置 OAM配置 去激活 xml:{}", oamXml);
        }
        // 获取网元信息， ip
        NetElement netElement = netElementService.getCacheObject(elementId);
        Device device = deviceManager.getDevice(netElement.getIp());
        if (device.isConnected()) {
            isSend = deviceManager.editConfig(vpwsXml.toString(), "merge");
            for (String policyXml : tunnelPolicyXmlList) {
                isSend = deviceManager.editConfig(policyXml, "merge");
            }
            for(String pwClassXml : pwClassXmlList) {
                isSend = deviceManager.editConfig(pwClassXml, "merge");
            }
            for(String oamXml : oamXmlList) {
                isSend = deviceManager.editConfig(oamXml, "merge");
            }
        }
        if (isSend) {
            updateElementStatus(l2VpnId, elementId, "0"); // 去激活
        }
        return isSend;
    }

    private String batchUnactivateL2Vpn(List<BusiL2VpnEleListVo> l2VpnEleListVos) {
        String status = "0";
        int unactivateCount = 0;
        for (BusiL2VpnEleListVo l2VpnEleListVo : l2VpnEleListVos) {
            try {
                if (unactivateElement(l2VpnEleListVo.getId(), l2VpnEleListVo.getElementId())) {
                    unactivateCount += 1;
                }
            } catch (Exception e) {
                // 批量去激活失败
                logger.error("批量去激活异常：", e);
            }
        }
        if (unactivateCount == l2VpnEleListVos.size()) {
            status = "1";
        } else if (unactivateCount == 0) {
            status = "0";
        } else if (unactivateCount < l2VpnEleListVos.size()) {
            status = "2";
        }
        return status;
    }

    /**
     * 修改单站业务激活状态
     * @param l2VpnId 业务id
     * @param elementId 网元id
     * @param status 激活状态
     */
    private int updateElementStatus(String l2VpnId, String elementId, String status) {
        BusiElementStatus busiElementStatus = new BusiElementStatus();
        busiElementStatus.setBusiId(l2VpnId);
        busiElementStatus.setElementId(elementId);
        List<BusiElementStatus> elementStatusList = busiElementStatusService.selectBusiElementStatusList(busiElementStatus);
        busiElementStatus = elementStatusList.get(0);
        busiElementStatus.setStatus(status); // 激活
        // 修改状态
        return busiElementStatusService.updateBusiElementStatus(busiElementStatus);
    }

    private String protectActivateDevice(String l2VpnId, String elementId) {
        String status = "0";
        boolean isSend = false;
        int activateCount = 0;
        // 业务基本信息
        BusiL2Vpn busiL2Vpn = busiL2VpnService.selectBusiL2VpnById(l2VpnId);
        // 判断当前网元类型 源网元、宿网元、备用宿网元
        BusiL2VpnEleListVo tempBusiL2VpnVo = new BusiL2VpnEleListVo();
        tempBusiL2VpnVo.setId(l2VpnId);
        List<BusiL2VpnEleListVo> list = busiL2VpnService.selectBusiL2VpnEleList(tempBusiL2VpnVo);
        BusiL2VpnEleListVo ne1 = new BusiL2VpnEleListVo();
        BusiL2VpnEleListVo ne2 = new BusiL2VpnEleListVo();
        BusiL2VpnEleListVo ne3 = new BusiL2VpnEleListVo();

        for (BusiL2VpnEleListVo vpnEleListVo : list) {
            if ("源网元".equals(vpnEleListVo.getNodeRole())) {
                ne1 = vpnEleListVo;
            } else if ("宿网元".equals(vpnEleListVo.getNodeRole())) {
                ne2 = vpnEleListVo;
            } else if ("备用宿网元".equals(vpnEleListVo.getNodeRole())) {
                ne3 = vpnEleListVo;
            }
        }
        for (BusiL2VpnEleListVo vpnEleListVo : list) {
            // xml报文列表
            List<String> alarmOamXmlList = new ArrayList<>();
            List<String> tunnelPolcyXmlList = new ArrayList<>();
            List<String> pwClassXmlList = new ArrayList<>();
            elementId = vpnEleListVo.getElementId();
            List<BusiL2VpnAlarmoam> alarmoamList = new ArrayList<>();
            if ("一源两宿".equals(busiL2Vpn.getNetworkMode())) {
                // OAM
                BusiL2VpnAlarmoam alarmoam = new BusiL2VpnAlarmoam();
                alarmoam.setL2VpnId(l2VpnId);
                alarmoam.setElementId(vpnEleListVo.getElementId());
                alarmoamList = alarmoamService.selectBusiL2VpnAlarmoamList(alarmoam);
                for (BusiL2VpnAlarmoam tempAlarmoam : alarmoamList) {
                    StringBuilder oamXml = new StringBuilder();
                    String[] meg = tempAlarmoam.getMeg().split("/");
                    String[] ttl = tempAlarmoam.getLspTtl().split("/");
                    oamXml.append("<tpoam xmlns=\"http://fiberhome.com/fhnw/yang/oam/fos-tpoam\">" +
                            "    <meg-cfg>" +
                            "      <meg-list>" +
                            "        <meg-name>" + tempAlarmoam.getMegName() + "</meg-name>" +//meg5b7d003f
                            "        <level>" + meg[4] + "</level>" +
                            "        <icc>" + meg[0] + "</icc>" +
                            "        <umc>" + meg[1] + "</umc>" +
                            "        <me-list>" +
                            "          <me-name>" + tempAlarmoam.getMeName() + "</me-name>" +
                            "          <mep-id>" + meg[2] + "</mep-id>" +
                            "          <remote-mep-id>" + meg[3] + "</remote-mep-id>" +
                            "          <mp-type>" + tempAlarmoam.getMpType() + "</mp-type>" + // mep
                            "          <ccm-send-enable>enable</ccm-send-enable>" +
                            "          <ccm-interval>" + tempAlarmoam.getCv() + "</ccm-interval>" +//3_33ms
                            "          <aps-send-enable>" + tempAlarmoam.getAps() + "</aps-send-enable>" + // disable
                            "          <fdi-send-enable>" + tempAlarmoam.getFdi() + "</fdi-send-enable>" + // disable
                            "          <csf-send-enable>" + tempAlarmoam.getCsf() + "</csf-send-enable>" + // disable
                            "          <oam-exp>" + ttl[1] + "</oam-exp>" +
                            "          <oam-ttl>" + ttl[0] + "</oam-ttl>" +
                            "          <dual-lm-enable>disable</dual-lm-enable>" +
                            "        </me-list>" +
                            "      </meg-list>" +
                            "    </meg-cfg>" +
                            "  </tpoam>");

                    alarmOamXmlList.add(oamXml.toString());
                }
            }
            // 获取pw
            List<String> partPwListXmlList = new ArrayList<>();
            BusiL2VpnPw busiL2VpnPw = new BusiL2VpnPw();
            busiL2VpnPw.setL2VpnId(l2VpnId);
            if ("源网元".equals(vpnEleListVo.getNodeRole())) {
                busiL2VpnPw.setStartElementId(vpnEleListVo.getElementId());
            } else if ("宿网元".equals(vpnEleListVo.getNodeRole())) {
                busiL2VpnPw.setEndElementId(vpnEleListVo.getElementId());
            } else if ("备用宿网元".equals(vpnEleListVo.getNodeRole())) {
                busiL2VpnPw.setEndElementId(vpnEleListVo.getElementId());
            }
            List<BusiL2VpnPwListVo> pws = new ArrayList<>();
            pws = l2VpnPwService.selectBusiL2VpnPwList(busiL2VpnPw);
            int i = 0;
            for (BusiL2VpnPwListVo pw : pws) {
                // 获取隧道策略
                BusiL2VpnTunnelStrategy tunnelStrategy = new BusiL2VpnTunnelStrategy();
                tunnelStrategy.setL2VpnId(pw.getL2VpnId());
                tunnelStrategy.setTunelBusiId(pw.getServiceLayerId());
                List<BusiL2VpnTunnelStrategy> tunnelStrategyList = tunnelStrategyService.selectBusiL2VpnTunnelStrategyList(tunnelStrategy);
                tunnelStrategy = tunnelStrategyList.get(0);
                // 配置隧道策略, 是否需要查询设备？ todo 2025-02-25
                String lsrIp = "";
                String tunnelId = "";
                BusiL2VpnNodeListVo nodeListVo = null;
                logger.info("调试获取tunnelId参数信息-protectActivateDevice：ServiceLayerId- startE- endE- role-"+ pw.getServiceLayerId() + "," + pw.getStartElementId() + "," + pw.getEndElementId() + "," + pw.getRole());
                if ("源网元".equals(vpnEleListVo.getNodeRole())) {
                    lsrIp = getLsrIpByElementId(pw.getEndElementId());
                    nodeListVo = getL2VpnNodeRole(l2VpnId, pw.getEndElementId());
                    tunnelId = getTunnelIdByServiceLayerIdAndElementId(pw.getServiceLayerId(), pw.getStartElementId(), pw.getRole());
                } else {
                    lsrIp = getLsrIpByElementId(pw.getStartElementId());
                    nodeListVo = getL2VpnNodeRole(l2VpnId, pw.getStartElementId());
                    tunnelId = getTunnelIdByServiceLayerIdAndElementId(pw.getServiceLayerId(), pw.getEndElementId(), pw.getRole());
                }
                StringBuilder tunnelPolicyXml = new StringBuilder();
                tunnelPolicyXml.append("<tnl-plcy xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-tunnelpolicy\">" +
                        "    <tunnel-policies>" +
                        "      <tunnel-policy-list>" +
                        "        <tunnel-policy-name>" + tunnelStrategy.getBusiName() + "</tunnel-policy-name>" + //pw-tnl-plcy-1534918722
                        "        <tunnel-policy-mode>" + tunnelStrategy.getTunnelStrategyMode() + "</tunnel-policy-mode>" +
                        "        <binding-policy>" +
                        "          <destination>" + lsrIp + "</destination>" +
//                        "          <tunnel-id>" + pw.getVcId() + "</tunnel-id>" +
                        "          <tunnel-id>" + tunnelId + "</tunnel-id>" +
                        "          <tunnel-down-switch>" + pw.getTunnelSwitch() + "</tunnel-down-switch>" +
                        "          <bind-tnnl-type>bind-tunnel</bind-tnnl-type>" +
                        "        </binding-policy>" +
                        "      </tunnel-policy-list>" +
                        "    </tunnel-policies>" +
                        "  </tnl-plcy>");
                tunnelPolcyXmlList.add(tunnelPolicyXml.toString());
                // PW-CLASS配置
                StringBuilder pwClassXml = new StringBuilder();
                pwClassXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                        "    <pw-class>" +
                        "      <pw-class-list>" +
                        "        <pw-class-name>" + pw.getPwClassName() + "</pw-class-name>" + // pwclassname-1534918719
                        "        <control-word>" + pw.getControlEnable() + "</control-word>" +
                        "        <tunnel-policy>" + tunnelStrategy.getBusiName() + "</tunnel-policy>" + //pw-tnl-plcy-1534918703
                        "      </pw-class-list>" +
                        "    </pw-class>" +
                        "  </l2vpn>");
                pwClassXmlList.add(pwClassXml.toString());

                StringBuilder partPwListXml = new StringBuilder();
                partPwListXml.append("<pw-list>" +
                        "          <peer-ip>" + lsrIp + "</peer-ip>" +
                        "          <pw-id>" + pw.getVcId() + "</pw-id>" +
                        "          <pw-type>raw</pw-type>" +
                        "          <static-transmit-label>" + pw.getOutLabel() + "</static-transmit-label>" +
                        "          <static-receive-label>" + pw.getInLabel() + "</static-receive-label>" +
                        "          <pw-role>" + ("备用宿网元".equals(nodeListVo.getNodeRole()) ? "secondary" : "primary") + "</pw-role>" +
                        "          <pw-class-name>" + pw.getPwClassName() + "</pw-class-name>");// + // pwclassname-1534918720
                if ("一源两宿".equals(busiL2Vpn.getNetworkMode())) {
                    partPwListXml.append("          <vcoam xmlns=\"http://fiberhome.com/fhnw/yang/oam/fos-tpoam\">" + //PW  OAM
                            "            <me-name>" + alarmoamList.get(i).getMeName() + "</me-name>" +
                            "          </vcoam>");
                }
                partPwListXml.append("        </pw-list>");
                partPwListXmlList.add(partPwListXml.toString());

                i++;
            }

            //VPWS实例配置
            StringBuilder vpwsXml = new StringBuilder();
            vpwsXml.append("<l2vpn xmlns=\"http://fiberhome.com/fhnw/yang/vpnservice/fos-l2vpn\">" +
                    "    <vpws>" +
                    "      <vpws-list>" +
                    "        <service-name>" + vpnEleListVo.getNodeBusiName() + "</service-name>"); //PW 保护属性
            if ("一源两宿".equals(busiL2Vpn.getNetworkMode()) && "源网元".equals(vpnEleListVo.getNodeRole())) {
                vpwsXml.append("        <wtr>5</wtr>" +
                        "        <holdtime>0</holdtime>" +
                        "        <revertive-mode>revertive</revertive-mode>" +
                        "        <protect-type>redundancy</protect-type>");
            }
            vpwsXml.append("        <accessif-list>" +
                    "          <ac-name>" + vpnEleListVo.getPortName() + "</ac-name>" +
                    "        </accessif-list>");
            for (String strPartPwListXml : partPwListXmlList) {
                vpwsXml.append(strPartPwListXml);
            }
            vpwsXml.append(//"        <vpws-qos-cfg xmlns=\"http://fiberhome.com/fhnw/yang/qos/fos-qos\"/>" +
                    "      </vpws-list>" +
                    "    </vpws>" +
                    "  </l2vpn>");
            for (String oamXml : alarmOamXmlList) {
                logger.info("L2VPN业务配置 OAM xml:{}", oamXml);
            }
            for (String tunnelPolicyXml : tunnelPolcyXmlList) {
                logger.info("L2VPN业务配置 配置隧道策略 xml:{}", tunnelPolicyXml);
            }
            for (String pwClassXml : pwClassXmlList) {
                logger.info("L2VPN业务配置 PW-CLASS配置 xml:{}", pwClassXml);
            }
            logger.info("L2VPN业务配置 VPWS实例配置 xml:{}", vpwsXml);
            NetElement netElement = netElementService.getCacheObject(elementId);
            Device device = deviceManager.getDevice(netElement.getIp());
            if (device.isConnected()) {
                for (String oamXml : alarmOamXmlList) {
                    // 配置OAM
                    isSend = deviceManager.editConfig(oamXml, "merge");
                }

                for (String tunnelPolicyXml : tunnelPolcyXmlList) {
                    // 配置隧道策略
                    isSend = deviceManager.editConfig(tunnelPolicyXml, "merge");
                }

                for (String pwClassXml : pwClassXmlList) {
                    // 配置PW-CLASS
                    isSend = deviceManager.editConfig(pwClassXml, "merge");
                }

                isSend = deviceManager.editConfig(vpwsXml.toString(), "merge");
                if (isSend) {
                    activateCount += updateElementStatus(l2VpnId, elementId, "1");
                }
            }
        }
        if (activateCount == list.size()) {
            status = "1";
        } else if (activateCount == 0) {
            status = "0";
        } else if (activateCount < list.size()) {
            status = "2";
        }
        return status;
    }

    /**
     * 通过网元id获取LsrIp
     * @param elementId
     * @return
     */
    private String getLsrIpByElementId(String elementId) {
        // 获取 lsp id
        ElementMplsLsrid elementMplsLsrid = new ElementMplsLsrid();
        elementMplsLsrid.setElementId(elementId);
        List<ElementMplsLsrid> lsrids = mplsLsridService.selectElementMplsLsridList(elementMplsLsrid);
        if (lsrids == null || lsrids.isEmpty()) {
            throw new RuntimeException("获取LSR ID失败");// 默认去loopback0对应的
        }
        lsrids = lsrids.stream().filter(lsrId -> lsrId.getLsrId().startsWith("loopback0")).collect(Collectors.toList());
        if (lsrids == null || lsrids.isEmpty()) {
            throw new RuntimeException("获取LSR ID失败, 缺少loopback0");// 默认去loopback0对应的
        }
        // <destination>100.1.1.2</destination>//关键字，隧道目的地址，目的网元的MPLS LSR ID
        return lsrids.get(0).getLsrId().replaceAll("\\)", "").split("\\(")[1];
    }

    /**
     * 获取L2VPN节点角色
     * @param l2VpnId
     * @param elementId
     */
    private BusiL2VpnNodeListVo getL2VpnNodeRole(String l2VpnId, String elementId) {
        // 获取L2VPN节点角色
        BusiL2VpnNode busiL2VpnNode = new BusiL2VpnNode();
        busiL2VpnNode.setL2VpnId(l2VpnId);
        busiL2VpnNode.setElementId(elementId);
        List<BusiL2VpnNodeListVo> nodes = nodeService.selectBusiL2VpnNodeList(busiL2VpnNode);
        return nodes.get(0);
    }
}